package com.ljw.spring.annotation.conf;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.EmbeddedValueResolver;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.StringValueResolver;

import javax.sql.DataSource;
import java.beans.PropertyVetoException;

/**
 * @FileName ConfigOfProfile
 * @Description TODO Profile：spring为我们提供的可以根据当前环境，动态激活和切换一系列bean组件的功能
 *              例如,数据源配置：
 *                  开发环境（数据源A）测试环境（数据源B）生产环境（数据源C）
 *               1. 从配置文件获取值3种方式
 *                  （1）属性字段上加：@Value("${db.user}")
 *                  （2）方法参数添加：getDataSourceTest(@Value("${db.password}")String password)
 *                  （3）从IOC容器获取spring底层组件StringValueResolver===》值解析器StringValueResolver：
 *                         a步：实现EmbeddedValueResolverAware接口，重写方法setEmbeddedValueResolver(StringValueResolver resolver)，
 *                              从IOC容器获取spring底层组件StringValueResolver为本类属性resolver赋值
 *                         b步： 用StringValueResolver调用方法resolveStringValue("${db.driverClass}")解析${db.driverClass}
 *               2. @Profile：指定组件bean在哪个环境下才能被注册到IOC容器中；若不指定环境，则任何bean组件都能被注册到IOC容器中。默认是default环境
 *                  @Profile(value = {"dev"}):加了该注解的bean，只有当这个dev环境被激活的时候，这个bean才能注册到IOC容器中
 *                  激活方式：
 *                  （1）命令行参数VM options设置为：-Dspring.profiles.active=test
 *                  （2）代码方式：context.getEnvironment().setActiveProfiles("test","dev");
 *                  （3）@Profile(value = {"test"})写在配置类上：表示只有当test环境激活时，这个配置类才起作用
 * @Author ljw
 * @Date 2021/2/3 11:36
 * @Version 1.0
 */
@Profile(value = {"test"})
@PropertySource(value = {"classpath:/db.properties"})
@Configuration
public class ConfigOfProfile implements EmbeddedValueResolverAware {

    private StringValueResolver valueResolver;
    private String driverClass;

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        this.valueResolver=resolver;
        //用从IOC容器获取的spring底层组件StringValueResolver解析${db.driverClass}
        driverClass = valueResolver.resolveStringValue("${db.driverClass}");
    }

    @Value("${db.user}")
    private String user;


    @Profile(value = {"test"})
    //测试数据源
    @Bean(value = {"testDataSource"})
    public DataSource getDataSourceTest(@Value("${db.password}")String password) throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");


        dataSource.setDriverClass(driverClass);
        return dataSource;
    }


    @Profile(value = {"dev"})
    //开发数据源
    @Bean(value = {"devDataSource"})
    public DataSource getDataSourceDev(@Value("${db.password}")String password) throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/dev");


        dataSource.setDriverClass(driverClass);
        return dataSource;
    }


    @Profile(value = {"prod"})
    //生产数据源
    @Bean(value = {"prodDataSource"})
    public DataSource getDataSourcePro(@Value("${db.password}")String password) throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setUser(user);
        dataSource.setPassword(password);
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/prop");


        dataSource.setDriverClass(driverClass);
        return dataSource;
    }


}
